/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.nestedConfigs;

import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.entity.dependenceTemp.DataValidator;
import com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.DataTypeDataGeneratorContext;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.element.ElementCollection;
import lombok.var;
import org.eclipse.jdt.core.dom.Block;

import java.util.HashMap;

import static com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType.*;
import static com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType.MultiColumns;

public class ComplexUdtMappingGenerator extends NestedMappingGenerator {
  private ComplexDataTypeDef getComplexUdt() {
    return (ComplexDataTypeDef) udt;
  }

  public ComplexUdtMappingGenerator(
      IGspCommonDataType dataType,
      IGspCommonField field,
      ComplexDataTypeDef udt,
      DataTypeDataGeneratorContext dataGenContext) {
    super(dataType, field, udt, dataGenContext);
  }

  @Override
  protected Block buildGetMethodBody() {
    HashMap<String, String> mapping = GetFieldMapping();
    return getMappingBolck(mapping);
  }

  private HashMap<String, String> GetFieldMapping() {
    HashMap<String, String> mapping = new java.util.HashMap<String, String>();
    switch (getComplexUdt().getDbInfo().getMappingType()) {
      case SingleColumn:
        mapping.put(field.getLabelID(), getComplexUdt().getCode());
        break;
      case MultiColumns:
    
        for (var item : field.getMappingRelation()) {
          IGspCommonField sourceField = findChildElement(item.getKeyInfo());
          IGspCommonField targetField = findUdtElement(getComplexUdt().getElements(), item.getValueInfo());
          DataValidator.checkForNullReference(sourceField, "sourceField");
          DataValidator.checkForNullReference(targetField, "TargetField");
          mapping.put(sourceField.getLabelID(), targetField.getLabelID());
        }
        break;
      default:
        throw new RuntimeException();
    }
    return mapping;
  }

  private IGspCommonField findUdtElement(ElementCollection collection, String elementID) {
    var ele1 = collection.getItem(elementID);
    if (ele1 != null) {
      return ele1;
    }
    for (var item : collection) {
      if (elementID.equals(item.getID())) {
        return item;
      }
      if (item.getChildElements() != null && item.getChildElements().size() != 0) {
    
        for (var item1 : item.getChildElements()) {
          if (elementID.equals(item1.getID())) {
            return item1;
          }
        }
      }
      if (item.getChildAssociations() != null && item.getChildAssociations().size() != 0) {
    
        for (var ass : item.getChildAssociations()) {
          if (ass.getRefElementCollection() == null || ass.getRefElementCollection().size() == 0) {
            continue;
          }
      
          for (var refElement : ass.getRefElementCollection()) {
            if (elementID.equals(refElement.getID())) {
              return refElement;
            }
          }
        }
      }
    }
    return null;
  }

  private IGspCommonField findChildElement(String elementID) {

    for (var item : field.getChildElements()) {
      if (elementID.equals(item.getID())) {
        return item;
      }
    }
    throw new RuntimeException();
  }
}
